package designpattern.singleton;

import java.io.*;
import java.lang.reflect.Constructor;

/**
 * @author or2
 * @Description 使用序列号破坏单例模式
 * @create 2021年09月01日 时间: 15:58
 */
public class DestroyBySerialization {

    public static void main(String[] args) throws Exception {
        StaticInnerClass instance = StaticInnerClass.getInstance();
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file_name"));
        oos.writeObject(instance);

        File file = new File("file_name");
//        此处可以通过实现 readResolve 避免, 否则会因为反射调用并返回导致 实例不一致
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        StaticInnerClass instance2 = (StaticInnerClass) ois.readObject();

        System.out.println(instance == instance2);

        Class<StaticInnerClass> objectClass = StaticInnerClass.class;
//        对于 类加载时完成实例化的(饿汉式, 静态内部类), 可以进行防御 - 但反射先执行的话就不行了 -> 业务逻辑代码防止(例如加flag)[但也可以相应逻辑破解]
        Constructor<StaticInnerClass> constructor = objectClass.getDeclaredConstructor();
        constructor.setAccessible(true);
        StaticInnerClass newInstance = constructor.newInstance();
        System.out.println("直接反射获得实例 与 单例的比较: " + (instance == newInstance));
    }
}
